<!DOCTYPE html>
<html>
<head>
    <title>Thermodynamic Diagram p-V</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
        }
        canvas {
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="thermoCanvas" width="550" height="550"></canvas>
    <script>
        const canvas = document.getElementById('thermoCanvas');
        const ctx = canvas.getContext('2d');

        // Style and font settings
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.lineWidth = 2;
        ctx.font = 'italic 20px "Times New Roman"';

        // Coordinates
        const O = { x: 80, y: 450 };
        const pAxisEnd = { x: O.x, y: 50 };
        const vAxisEnd = { x: 500, y: O.y };

        // Helper function to draw arrows
        function drawArrow(ctx, fromx, fromy, tox, toy) {
            const headlen = 10;
            const dx = tox - fromx;
            const dy = toy - fromy;
            const angle = Math.atan2(dy, dx);
            ctx.lineTo(tox, toy);
            ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(tox, toy);
            ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
        }

        // --- Start Drawing ---

        // 1. Draw Axes
        ctx.beginPath();
        ctx.moveTo(O.x, O.y);
        ctx.lineTo(vAxisEnd.x, vAxisEnd.y);
        ctx.moveTo(O.x, O.y);
        drawArrow(ctx, O.x, O.y, pAxisEnd.x, pAxisEnd.y);
        ctx.stroke();

        ctx.beginPath();
        ctx.moveTo(O.x, O.y);
        drawArrow(ctx, O.x, O.y, vAxisEnd.x, vAxisEnd.y);
        ctx.stroke();

        // Axis Labels
        ctx.fillText('p', pAxisEnd.x - 20, pAxisEnd.y);
        ctx.fillText('V', vAxisEnd.x + 15, vAxisEnd.y);
        ctx.fillText('O', O.x - 20, O.y + 20);

        // Point Coordinates
        const P1 = { x: 180, y: 140 };
        const P2 = { x: 230, y: 170 };
        const P3 = { x: 250, y: 200 };
        const P4 = { x: 310, y: 240 };
        const P5 = { x: 340, y: 270 };
        const P6 = { x: 410, y: 320 };
        
        // 2. Adiabatic Curves (Reference Lines)
        ctx.beginPath();
        ctx.moveTo(160, 115);
        ctx.bezierCurveTo(P1.x, P1.y, P3.x - 20, P3.y + 20, P5.x + 30, P5.y + 20);
        ctx.stroke();

        ctx.beginPath();
        ctx.moveTo(190, 150);
        ctx.bezierCurveTo(P2.x, P2.y, P4.x - 10, P4.y + 20, P6.x + 30, P6.y + 30);
        ctx.stroke();

        // 3. Solid lines connecting points (cycles)
        ctx.beginPath();
        // Cycle 1: 1-2-4-3-1
        ctx.moveTo(P1.x, P1.y);
        ctx.lineTo(P2.x, P2.y);
        ctx.moveTo(P2.x, P2.y);
        ctx.lineTo(P4.x, P4.y);
        ctx.moveTo(P4.x, P4.y);
        ctx.lineTo(P3.x, P3.y);
        ctx.moveTo(P3.x, P3.y);
        ctx.lineTo(P1.x, P1.y);
        // Cycle 2: 3-4-6-5-3
        ctx.moveTo(P3.x, P3.y);
        ctx.lineTo(P4.x, P4.y);
        ctx.moveTo(P4.x, P4.y);
        ctx.lineTo(P6.x, P6.y);
        ctx.moveTo(P6.x, P6.y);
        ctx.lineTo(P5.x, P5.y);
        ctx.moveTo(P5.x, P5.y);
        ctx.lineTo(P3.x, P3.y);
        ctx.stroke();

        // 4. Dashed construction lines
        ctx.save();
        ctx.setLineDash([4, 4]);
        ctx.lineWidth = 1.5;

        // From origin
        ctx.beginPath();
        ctx.moveTo(O.x, O.y);
        ctx.lineTo(P1.x, P1.y);
        ctx.moveTo(O.x, O.y);
        ctx.lineTo(P3.x, P3.y);
        ctx.moveTo(O.x, O.y);
        ctx.lineTo(P5.x, P5.y);

        // Projections to axes
        ctx.moveTo(P1.x, P1.y);
        ctx.lineTo(O.x, P1.y);
        ctx.moveTo(P1.x, P1.y);
        ctx.lineTo(P1.x, O.y);

        ctx.moveTo(P3.x, P3.y);
        ctx.lineTo(O.x, P3.y);
        ctx.moveTo(P3.x, P3.y);
        ctx.lineTo(P3.x, O.y);

        ctx.moveTo(P5.x, P5.y);
        ctx.lineTo(O.x, P5.y);
        
        ctx.stroke();
        ctx.restore();

        // 5. Point Labels (Numbers)
        ctx.font = 'bold 20px "Times New Roman"';
        ctx.fillText('1', P1.x - 15, P1.y - 5);
        ctx.fillText('2', P2.x - 5, P2.y - 15);
        ctx.fillText('3', P3.x - 15, P3.y + 5);
        ctx.fillText('4', P4.x - 5, P4.y - 15);
        ctx.fillText('5', P5.x - 15, P5.y + 5);
        ctx.fillText('6', P6.x, P6.y - 15);
        
        // 6. Axis Ticks and Labels
        ctx.font = 'italic 18px "Times New Roman"';
        const p_y_1 = P1.y;
        const p_y_2 = P3.y;
        const p_y_3 = P5.y;
        
        ctx.fillText('p', O.x - 25, p_y_1 - 5);
        ctx.fillText('3', O.x - 18, p_y_1 + 5);

        ctx.fillText('p', O.x - 25, p_y_2 - 5);
        ctx.fillText('2', O.x - 18, p_y_2 + 5);
        
        ctx.fillText('p', O.x - 25, p_y_3 - 5);
        ctx.fillText('1', O.x - 18, p_y_3 + 5);
        
        // Draw little dots/circles for the ticks
        ctx.beginPath();
        ctx.arc(O.x, p_y_1, 2, 0, 2 * Math.PI);
        ctx.fill();
        ctx.beginPath();
        ctx.arc(O.x, p_y_2, 2, 0, 2 * Math.PI);
        ctx.fill();
        ctx.beginPath();
        ctx.arc(O.x, p_y_3, 2, 0, 2 * Math.PI);
        ctx.fill();

        // 7. Chinese Text Labels
        ctx.font = '22px "KaiTi"';
        ctx.fillText('绝热线', 420, 290);
        ctx.fillText('绝热线', 460, 370);
        
        // Figure Caption
        ctx.font = '20px "SimSun"';
        ctx.fillText('热图 2.18.1', canvas.width / 2, 520);
    </script>
</body>
</html>